package com.zp.self.module.level_1_问道.X_JDK8新功能.Stream;

import com.zp.self.module.level_1_问道.X_JDK8新功能.Stream.entity.Employee;
import org.junit.Test;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.stream.Collectors;
import java.util.stream.IntStream;
import java.util.stream.Stream;

/**
 * @author By ZengPeng
 * @Description 中间操作:一个流可以有零个或者多个中间操作，每一个中间操作都会返回一个新的流，供下一个操作使用。
 *                 1、筛选与切片
 *                 2、映射
 *                 3、排序
 * @date in  2021/3/2 10:06
 * @Modified By
 */
public class b中间操作 {

    @Test
    //-------------------------------------------1、筛选与切片  -------------------------------------------
    //    包括：
    //          filter  过滤
    //          limit  前几
    //          skip   排除前几
    //          distinct 去重元素。注意自定义对象需要重写 equals 和 hashCode方法
    public void testStream(){
        ArrayList<Employee> list = new ArrayList<>();
        list.add(new Employee("张三",3000));
        list.add(new Employee("李四",5000));
        list.add(new Employee("王五",4000));
        list.add(new Employee("赵六",4500));
        list.add(new Employee("赵六",4500));

        // filter，过滤出工资大于4000的员工
        list.stream()
                .filter((e) -> e.getSalary() > 4000)
                .forEach(System.out::println);

        System.out.println("===============");
        // limit，限定指定个数的元素
        list.stream()
                .limit(3)
                .forEach(System.out::println);

        System.out.println("===============");
        // skip，和 limit 正好相反，跳过前面指定个数的元素
        list.stream()
                .skip(3)
                .forEach(System.out::println);

        System.out.println("===============");
        // distinct，去重元素。注意自定义对象需要重写 equals 和 hashCode方法
        list.stream()
                .distinct()
                .forEach(System.out::println);
    }


    //-------------------------------------------2、映射  -------------------------------------------
    //   映射：
    //          map     映射。eg:每个元素都乘以2
    //          mapToInt  同上
    //          mapToLong 同上
    //          mapToDouble 同上
    //          flatMap   可以把二维的集合映射成一维的。看起来，就像把二维集合压平似的。（ flat 的英文意思就是压平）
    @Test
    public void mapping(){
        int[] arr = {10,20,30,40,50};
        // map，映射。每个元素都乘以2
        Arrays.stream(arr)
                .map(e -> e * 2)
                .forEach(System.out::println);

        System.out.println("===============");
        //mapToInt,mapToDouble,mapToLong 用法都一样，不同的是返回类型分别是
        //IntStream,DoubleStream,LongStream.
        Arrays.stream(arr)
                .mapToDouble(e -> e * 2 )
                .forEach(System.out::println);

        System.out.println("===============");
        Arrays.stream(arr)
                .flatMap(e -> IntStream.of(e * 2))
                .forEach(System.out::println);


    }
    // flatMap   可以把二维的集合映射成一维的。看起来，就像把二维集合压平似的。（ flat 的英文意思就是压平）
    //现在给出这样的数据，若想返回所有水果单词的所有字母（"appleorangebanana"），应该怎么做？
    @Test
    public void mapping2flatMap(){
        //慢 slow   ：forEach 遍历就两次。
        String[] fruits = {"apple","orange","banana"};
        Stream.of(fruits).map((s) -> Stream.of(s.split("")))
                .forEach(e -> e.forEach(System.out::print));

        System.out.println("===============");
//        Stream.of(fruits).map((s) -> Stream.of(s.split("")))
//                .map(e -> Stream.of(e))
//                .forEach(System.out::print);

        System.out.println("===============");
        Stream.of(fruits).map(s -> s.split(""))
                .flatMap(e -> Stream.of(e))
                .forEach(System.out::print);

        //这里已经处理成集合了
        Stream.of(fruits).flatMap(s -> Stream.of(s.split("")))
                .collect(Collectors.toList())
                .forEach(System.out::print);
    }


    //-------------------------------------------3、排序  -------------------------------------------
    //   sorted()
    //   sorted(Comparator<? super T> comparator)
    @Test
    public void sorted(){
        String[] arr = {"abc","aa","ef"};
        //默认升序（字典升序）
        Stream.of(arr)
                .sorted()
                .forEach(System.out::println);
        System.out.println("=====");
        //自定义排序，字典降序
        Stream.of(arr).
                sorted((s1,s2) -> s2.compareTo(s1)).
                forEach(System.out::println);
    }
}
